package tests

import (
	"archive/zip"
	"bytes"
	"encoding/json"
	"os"
	"testing"

	"notabug.org/Umnik/GoAndroidSDK/v2/components/sdk/buildTools/aapt"
)

func newAapt(t *testing.T, funcName string) *aapt.Aapt {
	t.Helper()
	a, err := aapt.NewAaptLastVersion(*newSdk(t, t.Name()))
	if !testErr(t, funcName, err) {
		return nil
	}
	return a
}

func aaptInfo(t *testing.T, file string, funcName string) *aapt.AppInfo {
	t.Helper()
	aw := newAapt(t, funcName)
	b, err := aw.DumpAppInfo(file)
	if !testErr(t, t.Name(), err) {
		return nil
	}
	res := aapt.ParseAppInfoDumpFromBytes(b)
	return &res
}

func TestAaptVersion(t *testing.T) {
	t.Parallel()
	aw := newAapt(t, t.Name())
	b, err := aw.Version()
	if !testErr(t, t.Name(), err) {
		return
	}
	if !bytes.HasPrefix(b, []byte("Android Asset Packaging Tool, v")) {
		t.Errorf("%v: cannot find version in %q", t.Name(), b)
	}
}

func TestAaptMinSdk(t *testing.T) {
	t.Parallel()
	info := aaptInfo(t, goodApkFile(), t.Name())
	if info.MinSDKVersion != 23 {
		t.Errorf("%v: min sdk version is %v", t.Name(), info.MinSDKVersion)
	}
}

func TestAaptTargetSdk(t *testing.T) {
	t.Parallel()
	info := aaptInfo(t, goodApkFile(), t.Name())
	if info.TargetSDKVersion != 32 {
		t.Errorf("%v: target sdk version is %v", t.Name(), info.TargetSDKVersion)
	}
}

func TestAaptRemoveSign(t *testing.T) {
	t.Parallel()
	temp, err := os.CreateTemp("", "aapt-*")
	if !testErr(t, t.Name(), err) {
		return
	}
	defer removeOsFile(t, t.Name(), temp.Name())

	if !makeCopy(t, t.Name(), temp, goodApkFile()) {
		return
	}

	a := newAapt(t, t.Name())
	if _, err = a.RemoveSignature(temp.Name()); err != nil {
		t.Fatal(err)
	}

	tmpReader, err := zip.OpenReader(temp.Name())
	if !testErr(t, t.Name(), err) {
		return
	}
	defer closeZipFile(t, t.Name(), tmpReader)

	for _, fileName := range tmpReader.File {
		if fileName.Name == "META-INF/CERT.SF" ||
			fileName.Name == "META-INF/CERT.DSA" ||
			fileName.Name == "META-INF/MANIFEST.MF" {
			t.Errorf("File %q was not removed", fileName.Name)
		}
	}
}

func TestAaptJson(t *testing.T) {
	t.Parallel()
	info := aaptInfo(t, split_base(), t.Name())

	b, err := json.MarshalIndent(info, "", "\t")
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%s", b)
}
